package com.dingding.special.user.deposit.biz.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.base.dto.ResponseEntity;
import com.dingding.common.core.beans.special.Specialaccounttradedetail;
import com.dingding.common.core.beans.special.Specialdepositrecord;
import com.dingding.common.core.beans.special.Specialuseraccount;
import com.dingding.common.core.beans.special.Specialuserlogin;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.common.core.util.paravalidate.ValiResult;
import com.dingding.common.core.util.paravalidate.ValidateUtil;
import com.dingding.special.user.account.dao.ISpecialAccountTradeDetailDao;
import com.dingding.special.user.account.dao.ISpecialUserAccountDao;
import com.dingding.special.user.deposit.biz.IUserDepositService;
import com.dingding.special.user.deposit.code.DepositCodeMsg;
import com.dingding.special.user.deposit.dao.IUserDepositDao;
import com.dingding.special.user.deposit.dto.DepositDetailDTO;
import com.dingding.special.user.deposit.dto.ReqUserDepositDTO;
import com.dingding.special.user.deposit.dto.ReqUserDepositDetailDTO;
import com.dingding.special.user.deposit.dto.ResUserDepositDTO;
import com.dingding.special.user.deposit.dto.ResUserDepositDetailDTO;

/**
 * 
 * @ClassName: UserDepositServiceImpl 
 * @Description: 用户提现Service实现类 
 * @author YHQ
 * @date 2016年8月18日 下午9:34:19
 * @since V2.4.0
 * 
 */
@Component("userDepositService")
public class UserDepositServiceImpl implements IUserDepositService{

	private Logger log = Logger.getLogger(this.getClass());
	
	@Resource(name="specialUserAccountDao")
	private ISpecialUserAccountDao specialUserAccountDao;
	
	@Resource(name="userDepositDao")
	private IUserDepositDao userDepositDao;
	
	@Resource(name="specialAccountTradeDetailDao")
	private ISpecialAccountTradeDetailDao specialAccountTradeDetailDao;
	
	/**
	 * 
	 * @Title: takeMoney 
	 * @Description: 提现 
	 * @param reqUserDepositDTO 提现参数
	 * @author YHQ 
	 * @since V2.4.0
	 * @return ResponseEntity<ResUserDepositDTO>    返回类型
	 * 
	 */
	@Override
	@Transactional(propagation=Propagation.REQUIRED)
	public ResponseEntity<ResUserDepositDTO> takeMoney(ReqUserDepositDTO reqUserDepositDTO) {
		
		// 响应客户端Bean
		ResponseEntity<ResUserDepositDTO> response = new ResponseEntity<ResUserDepositDTO>();
		
		// 验证请求参数是否为空
		boolean flag = this.validateDeposit(response, reqUserDepositDTO);
		
		if(!flag){
			return response;
		}
		
		// 提现操作
		this.depositOperation(response, reqUserDepositDTO);
		
		return response;
	}

	/**
	 * 
	 * @Title: validateDeposit 
	 * @Description: 验证提现请求参数 
	 * @param validateDeposit 
	 * @author YHQ 
	 * @since V2.4.0
	 * @return boolean    返回类型
	 * 
	 */
	public boolean validateDeposit(ResponseEntity<ResUserDepositDTO> response,ReqUserDepositDTO reqUserDepositDTO){
		
		// 判断客户端请求数据是否为空
		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqUserDepositDTO, ReqUserDepositDTO.class);
		
		if (!valiResult.isAvailable()) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(DepositCodeMsg.DATA_NULL_PARAM_MESSAGE);// 客户端请求数据为空
			response.setPromptMessage(DepositCodeMsg.APP_ERROR);// 客户端请求数据为空
			response.setNullProperties(valiResult.getNullFieldName());
			log.error("为空字段为：" + valiResult.getNullFieldName());
			return false;
		}
		
		return true;
	}
	
	/**
	 * 
	 * @Title: depositOperation 
	 * @Description: 提现操作 
	 * @param reqUserDepositDTO 提现参数
	 * @author YHQ 
	 * @since V2.4.0
	 * @return void    返回类型
	 * 
	 */
	@Transactional(propagation=Propagation.REQUIRED)
	public void depositOperation(ResponseEntity<ResUserDepositDTO> response,ReqUserDepositDTO reqUserDepositDTO){
		
		// 响应Bean
		ResUserDepositDTO resUserDepositDTO = new ResUserDepositDTO();
		
		// 获取专车用户登录信息
		Specialuserlogin specialuserlogin = specialUserAccountDao.getSpecialUserLogin(reqUserDepositDTO.getUserId());
		
		// 获取专车司机的账户信息
		Specialuseraccount specialuseraccount = specialUserAccountDao.getSpecialUserAccount(reqUserDepositDTO.getUserId());
		
		// 用户账户信息不存在
		if(specialuserlogin == null ||specialuseraccount == null){
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(DepositCodeMsg.USER_IS_NOT_EXIST);// 用户不存在
			response.setPromptMessage(DepositCodeMsg.USER_IS_NOT_EXIST);// 用户不存在
			return;
		}
		
		// 判断当日是否还能提现
		if(specialuserlogin.getDepositNumber() != null && specialuserlogin.getDepositNumber() >= 1){
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(DepositCodeMsg.DEPOSIT_NUMBER_INSUFFICIENT);// 无提现次数
			response.setPromptMessage(DepositCodeMsg.DEPOSIT_NUMBER_INSUFFICIENT);// 无提现次数
			return;
		}
		
		// 判断是否余额是否充足
		if(specialuseraccount.getCurrencyAmount().compareTo((reqUserDepositDTO.getDepositMoney().add(specialuseraccount.getFreezeCashAmount()))) < 0){
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(DepositCodeMsg.INSUFFICIENT_BALANCE);// 余额不足
			response.setPromptMessage(DepositCodeMsg.INSUFFICIENT_BALANCE);// 余额不足
			return;
		}
		
		// 添加一条提现明细
		boolean flag = this.addDepositRecord(reqUserDepositDTO);
		
		if(!flag){
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(DepositCodeMsg.DEPOSIT_FAIL_ERROR);// 提现失败
			response.setPromptMessage(DepositCodeMsg.DEPOSIT_FAIL_ERROR);// 提现失败
			return;
		}
		
		// 提现冻结金额
		specialuseraccount.setFreezeCashAmount(specialuseraccount.getFreezeCashAmount().add(reqUserDepositDTO.getDepositMoney()));
		
		// 设置本日提现次数
		specialuserlogin.setDepositNumber(1);
		
		resUserDepositDTO.setDepositStatus(1);
		
		response.setCode(HttpStatus.SC_OK);
		response.setResponseBody(resUserDepositDTO);
	}
	
	/**
	 * 
	 * @Title: addDepositRecord 
	 * @Description: 添加一条提现记录
	 * @param reqUserDepositDTO 提现请求参数
	 * @author YHQ 
	 * @since V2.4.0 
	 * @return boolean    返回类型
	 * 
	 */
	public boolean addDepositRecord(ReqUserDepositDTO reqUserDepositDTO){
		
		// 创建提现对象
		Specialdepositrecord specialdepositrecord = new Specialdepositrecord();
		
		// 提现用户Id
		specialdepositrecord.setUserId(reqUserDepositDTO.getUserId());
		// 提现金额
		specialdepositrecord.setDepositMoney(reqUserDepositDTO.getDepositMoney());
		// 支付宝账号
		specialdepositrecord.setZfbAccount(reqUserDepositDTO.getZfbAccount());
		// 支付宝名称
		specialdepositrecord.setZfbName(reqUserDepositDTO.getZfbName());
		
		// 提现记录主键
		specialdepositrecord.setSddId(ToolUtil.getUid());
		// 提现时间
		specialdepositrecord.setDepositTime(new Date());
		// 提现状态
		specialdepositrecord.setDepositStatus(1);
		
		return userDepositDao.addSpecialDepositRecord(specialdepositrecord);
	}

	
	/**
	 * 
	 * @Title: depositDetail 
	 * @Description: 提现明细 
	 * @param reqUserDepositDetailDTO 客户端请求参数
	 * @author YHQ 
	 * @since V2.4.0 
	 * @return ResponseEntity<ResUserDepositDetailDTO>    返回类型
	 * 
	 */
	@Override
	public ResponseEntity<ResUserDepositDetailDTO> depositDetail(ReqUserDepositDetailDTO reqUserDepositDetailDTO) {
		
		ResponseEntity<ResUserDepositDetailDTO> response = new ResponseEntity<ResUserDepositDetailDTO>();
		
		// 获取用户提现明细响应Bean
		ResUserDepositDetailDTO resUserDepositDetailDTO = new ResUserDepositDetailDTO();
		
		boolean flag = this.validateDepositDetail(response, reqUserDepositDetailDTO);
		
		if(!flag){
			return response;
		}
		
		// 获取提现列表
		this.getDepositDetailList(resUserDepositDetailDTO, reqUserDepositDetailDTO);
		
		// 获取总支出、总收入和总提现
		this.cumulativeDetail(resUserDepositDetailDTO, reqUserDepositDetailDTO.getUserId());
		
		response.setResponseBody(resUserDepositDetailDTO);
		response.setCode(HttpStatus.SC_OK);
		
		return response;
	}
	
	/**
	 * 
	 * @Title: validateDeposit 
	 * @Description: 验证提现请求参数 
	 * @param validateDeposit 
	 * @author YHQ 
	 * @since V2.4.0
	 * @return boolean    返回类型
	 * 
	 */
	public boolean validateDepositDetail(ResponseEntity<ResUserDepositDetailDTO> response,ReqUserDepositDetailDTO reqUserDepositDetailDTO){
		
		// 判断客户端请求数据是否为空
		ValiResult valiResult = ValidateUtil.validateBeanIsAvaliable(reqUserDepositDetailDTO, ReqUserDepositDetailDTO.class);
		
		if (!valiResult.isAvailable()) {
			response.setCode(HttpStatus.SC_FORBIDDEN);
			response.setErrorMessage(DepositCodeMsg.DATA_NULL_PARAM_MESSAGE);// 客户端请求数据为空
			response.setPromptMessage(DepositCodeMsg.APP_ERROR);// 客户端请求数据为空
			response.setNullProperties(valiResult.getNullFieldName());
			log.error("为空字段为：" + valiResult.getNullFieldName());
			return false;
		}
		
		return true;
	}
	
	/**
	 * 
	 * @Title: getDepositDetailList 
	 * @Description: 获取提现列表 
	 * @param  
	 * @author YHQ 
	 * @since V2.4.0
	 * @return void    返回类型
	 * 
	 */
	public void getDepositDetailList(ResUserDepositDetailDTO resUserDepositDetailDTO,ReqUserDepositDetailDTO reqUserDepositDetailDTO){
		
		// 获取提现列表
		List<Specialdepositrecord> specialdepositrecords = userDepositDao.getSpecialDepositRecord(reqUserDepositDetailDTO.getUserId(),reqUserDepositDetailDTO.getPageIndex(),reqUserDepositDetailDTO.getPageSize());
		
		
		if(specialdepositrecords != null && specialdepositrecords.size() > 0){
			
			// 用户提现明细列表
			List<DepositDetailDTO> depositDetailDTOs = new ArrayList<DepositDetailDTO>();
			
			for (Specialdepositrecord specialdepositrecord : specialdepositrecords) {
				
				// 提现明细响应DTO
				DepositDetailDTO depositDetailDTO = new DepositDetailDTO();
				
				// 提现描述
				depositDetailDTO.setDepositDescription(specialdepositrecord.getDepositDescription());
				// 提现金额
				depositDetailDTO.setDepositMoney(specialdepositrecord.getDepositMoney());
				// 提现状态  1：待处理 2：处理中 3：成功 4：失败
				depositDetailDTO.setDepositStatus(specialdepositrecord.getDepositStatus());
				// 提现时间
				depositDetailDTO.setDepositTime(DateFormatUtil.yyyy_MM_dd_HHmmss(specialdepositrecord.getDepositTime()));
				// 支付宝账号
				depositDetailDTO.setZfbAccount(specialdepositrecord.getZfbAccount());
				// 支付宝名称
				depositDetailDTO.setZfbName(specialdepositrecord.getZfbName());
				
				depositDetailDTOs.add(depositDetailDTO);
			}
			
			resUserDepositDetailDTO.setDepositDetailList(depositDetailDTOs);
		}
		
	}
	
	/**
	 * 
	 * @Title: cumulativeDetail 
	 * @Description: 累计明细(总支出、总收入和总提现)
	 * @param userId 用户id
	 * @author YHQ 
	 * @since V2.4.0
	 * @return void    返回类型
	 * 
	 */
	public void cumulativeDetail(ResUserDepositDetailDTO resUserDepositDetailDTO,String userId){
		
		// 根据用户Id专车用户账号交易明细列表
		List<Specialaccounttradedetail> specialaccounttradedetails = specialAccountTradeDetailDao.getSpecialAccountTradeDetail(userId);
		
		// 累计收入
		BigDecimal cumulativeIncome = new BigDecimal(0);
		// 累计提现
		BigDecimal cumulativeDeposit = new BigDecimal(0);
		
		if(specialaccounttradedetails != null && specialaccounttradedetails.size() > 0){
			
			for (Specialaccounttradedetail specialaccounttradedetail : specialaccounttradedetails) {
				
				if(specialaccounttradedetail.getTradeType() == 1){ // 专车订单收入
					cumulativeIncome = cumulativeIncome.add(specialaccounttradedetail.getTradeMoney());
				}else if(specialaccounttradedetail.getTradeType() == 2){ // 提现
					cumulativeDeposit = cumulativeDeposit.add(specialaccounttradedetail.getTradeMoney());
				}
				
			}
		}
		
		// 累计提现
		resUserDepositDetailDTO.setTotalDeposit(cumulativeDeposit);
		// 累计收入
		resUserDepositDetailDTO.setTotalIncome(cumulativeIncome);
		// 累计支出
		resUserDepositDetailDTO.setTotalExpend(new BigDecimal(0));
		
	}
	
}
